home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 December: Technology Seed / ADC Seed CD - Dec'98.toast / FireWire / FireWire 1.3 SDK DR1 / Source / SBP2 / SBP2DemoApp / SBP2DemoApp.c next >
Encoding:
C/C++ Source or Header  |  1998-09-21  |  45.6 KB  |  2,055 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SBP2DemoApp.c
  3.  
  4.     Contains:    A simple application to demonstrate using the SBP-2 sample driver.
  5.  
  6.     Version:    1.0
  7.  
  8.     Copyright:    © 1998 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                Eric Anderson
  13.  
  14.         Other Contact:        
  15.  
  16.         Technology:            FireWire
  17.  
  18.     Writers:
  19.  
  20.         (EA)    Eric Anderson (ewa)
  21.  
  22.     Change History (most recent first):
  23.  
  24.        <FW2>     9/20/98    EA        Filled in header comments.
  25.        <FW1>     9/20/98    EA        first checked in
  26. */
  27.  
  28.  
  29. #include <Types.h>
  30. #include <Memory.h>
  31. #include <Devices.h>
  32. #include <Resources.h>
  33. #include <QuickDraw.h>
  34. #include <Fonts.h>
  35. #include <Events.h>
  36. #include <AppleEvents.h>
  37. #include <EPPC.h>
  38. #include <Windows.h>
  39. #include <Menus.h>
  40. #include <Dialogs.h>
  41. #include <ToolUtils.h>
  42. #include <DiskInit.h>
  43. #include <FireWireSBP2.h>
  44. #include <SampleSBP2.h>
  45. #include <SBP2DemoApp.h>
  46.  
  47. #include <TextUtils.h>
  48. #include <stdio.h>
  49. char    debugStr[256];
  50.  
  51. ////////////////////////////////////////////////////////////////////////////////
  52. //
  53. // Define global structure to hold all of the SBP2Demo data.
  54. //
  55.  
  56. SBP2DemoAppDataPtr                gpSBP2DemoAppData = nil;
  57. Boolean                            quitSBP2DemoApp = false;
  58.  
  59.  
  60. ////////////////////////////////////////////////////////////////////////////////
  61. //
  62. // Internal procedure prototypes.
  63. //
  64.  
  65. static void    SBP2DemoEventLoop (void);
  66.  
  67. static OSErr    HandleEvent (
  68.     EventRecord                    *pEventRecord);
  69.  
  70. static OSErr    HandleMouseDownEvent (
  71.     EventRecord                    *pEventRecord);
  72.  
  73. static OSErr    HandleKeyEvent (
  74.     EventRecord                    *pEventRecord);
  75.  
  76. static OSErr    HandleOSEvent (
  77.     EventRecord                    *pEventRecord);
  78.  
  79. static OSErr    HandleMenuCommand (
  80.     long                        menuCommand);
  81.  
  82. static OSErr    HandleAppleMenuCommand (
  83.     short                        menuItem);
  84.  
  85. static OSErr    HandleFileMenuCommand (
  86.     short                        menuItem);
  87.  
  88. static OSErr    HandleCommandMenuCommand (
  89.     short                        menuItem);
  90.  
  91. static OSErr    HandleCloseFileMenuCommand (void);
  92.  
  93. static OSErr    HandleLoginMenuCommand (void);
  94.  
  95. static OSErr    HandleLogoutMenuCommand (void);
  96.  
  97. static OSErr    HandleStatusInquiryMenuCommand (void);
  98.  
  99. static OSErr    HandleModeSenseMenuCommand (void);
  100.  
  101. static OSErr    HandleReadBlockMenuCommand (void);
  102.  
  103. static OSErr    HandleWindowCommand (
  104.     WindowRef                    windowRef);
  105.  
  106. static OSErr    SBP2DemoInitialize (void);
  107.  
  108. static OSErr    QuitApplication (void);
  109.  
  110. static OSErr    CreateSBP2Demo (
  111.     SBPDriverID                    sbpDriverID);
  112.  
  113. static OSErr    RemoveSBP2Demo (
  114.     SBPDriverID                    sbpDriverID);
  115.  
  116. static OSErr    CloseSBP2DemoWindow (
  117.     WindowRef                    windowRef);
  118.  
  119. static OSErr    DrawSBP2Demo (
  120.     WindowRef                    windowRef);
  121.  
  122. static OSErr    UpdateWindow (
  123.     WindowRef                    windowRef);
  124.  
  125. static OSErr    UpdateMenus (void);
  126.  
  127. static OSErr    UpdateCursor (
  128.     Point                        mousePosition,
  129.     RgnHandle                    hCursorRgn);
  130.  
  131. static Boolean    IsSBP2DemoWindow (
  132.     WindowRef                    windowRef);
  133.  
  134. static void    GetMousePosition (
  135.     Point                        *pMousePosition);
  136.  
  137. static pascal OSErr    HandleOpenApplicationEvent (
  138.     AppleEvent                    *theAppleEvent,
  139.     AppleEvent                    *reply,
  140.     long                        handlerRefcon);
  141.  
  142. static pascal OSErr    HandleOpenDocumentsEvent (
  143.     AppleEvent                    *theAppleEvent,
  144.     AppleEvent                    *reply,
  145.     long                        handlerRefcon);
  146.  
  147. static pascal OSErr    HandlePrintDocumentsEvent (
  148.     AppleEvent                    *theAppleEvent,
  149.     AppleEvent                    *reply,
  150.     long                        handlerRefcon);
  151.  
  152. static pascal OSErr    HandleQuitApplicationEvent (
  153.     AppleEvent                    *theAppleEvent,
  154.     AppleEvent                    *reply,
  155.     long                        handlerRefcon);
  156.  
  157. static pascal OSErr    HandleDeviceAddedEvent (
  158.     AppleEvent                    *theAppleEvent,
  159.     AppleEvent                    *reply,
  160.     long                        handlerRefcon);
  161.  
  162. static pascal OSErr    HandleDeviceRemovedEvent (
  163.     AppleEvent                    *theAppleEvent,
  164.     AppleEvent                    *reply,
  165.     long                        handlerRefcon);
  166.  
  167. static SBP2DemoDataPtr    FindSBP2DemoFromSBPDriver (
  168.     SBPDriverID                    sbpDriverID);
  169.  
  170. static OSErr    RemoveSBP2DemoFromList (
  171.     SBP2DemoDataPtr            pSBP2DemoData);
  172.  
  173. static OSErr    PrepareWindowForUpdating (
  174.     WindowRef                    windowRef,
  175.     Boolean                        *pUpdateNeeded);
  176.  
  177. static OSErr    ReleaseWindowFromUpdating (
  178.     WindowRef                    windowRef);
  179.  
  180. static void    CheckAllDevices (void);
  181.  
  182.  
  183. ////////////////////////////////////////////////////////////////////////////////
  184. ////////////////////////////////////////////////////////////////////////////////
  185. //
  186. // Exported routines.
  187. //
  188. ////////////////////////////////////////////////////////////////////////////////
  189. ////////////////////////////////////////////////////////////////////////////////
  190.  
  191. ////////////////////////////////////////////////////////////////////////////////
  192. //
  193. // SBP2DemoMain
  194. //
  195. //   This routine is the main entry point for the SBPSBP2Demo
  196. // application.
  197. //
  198.  
  199. SBP2DemoMain()
  200. {
  201.     OSErr                        err = noErr;
  202.  
  203.     // Initialize the application.
  204.     err = SBP2DemoInitialize ();
  205.  
  206.     // Main application event loop.
  207.     if (err == noErr)
  208.         SBP2DemoEventLoop ();
  209.  
  210.     // Dispose of app data.
  211.     if (gpSBP2DemoAppData != nil)
  212.         QuitApplication ();
  213.  
  214.     return (err);
  215. }
  216.  
  217.  
  218. ////////////////////////////////////////////////////////////////////////////////
  219. ////////////////////////////////////////////////////////////////////////////////
  220. //
  221. // Internal routines.
  222. //
  223. ////////////////////////////////////////////////////////////////////////////////
  224. ////////////////////////////////////////////////////////////////////////////////
  225.  
  226. ////////////////////////////////////////////////////////////////////////////////
  227. //
  228. // SBP2DemoEventLoop
  229. //
  230. //   This routine is the main event loop for the SBPSBP2Demo
  231. // application.
  232. //
  233.  
  234. static void    SBP2DemoEventLoop(void)
  235. {
  236.     RgnHandle                    hCursorRgn;
  237.     Point                        mousePosition;
  238.     EventRecord                    eventRecord;
  239.     Boolean                        gotEvent;
  240.     OSErr                        err = noErr;
  241.  
  242.     // Initialize cursor region.
  243.     hCursorRgn = NewRgn ();
  244.     if (hCursorRgn == nil)
  245.         err = memFullErr;//zzz is this right?
  246.  
  247.     // Main event loop.
  248.     while ((!quitSBP2DemoApp) && (err == noErr))
  249.     {
  250.         // Update cursor to correct image.
  251.         GetMousePosition (&mousePosition);
  252.         err = UpdateCursor (mousePosition, hCursorRgn);
  253.  
  254.         // Get any SBP events.
  255.         if (err == noErr)
  256.             err = GetNextSBPClientEvent (gpSBP2DemoAppData->sbpClientID);
  257.  
  258.         // Wait for next event.
  259.         if (err == noErr)
  260.             gotEvent = WaitNextEvent (everyEvent, &eventRecord, 1, hCursorRgn);
  261.  
  262.         // Handle event if we got one.
  263.         if (err == noErr)
  264.         {
  265.             if (gotEvent)
  266.             {
  267.                 // Update cursor to correct image.
  268.                 err = UpdateCursor (eventRecord.where, hCursorRgn);
  269.     
  270.                 // Handle the event.
  271.                 if (err == noErr)
  272.                     err = HandleEvent (&eventRecord);
  273.             }
  274.         }
  275.         
  276.         // Check status of all SBP devices.
  277.         // This is a bad design - we are polling every time, even if nothing changes.
  278.         if (!quitSBP2DemoApp) CheckAllDevices ();
  279.     }
  280. }
  281.  
  282.  
  283. ////////////////////////////////////////////////////////////////////////////////
  284. //
  285. // HandleEvent
  286. //
  287. //   This routine handles the given event.
  288. //
  289.  
  290. static OSErr    HandleEvent(
  291.     EventRecord                    *pEventRecord)
  292. {
  293.     Point                        point;
  294.     OSErr                        err = noErr;
  295.  
  296.     // Main event dispatcher.
  297.     switch (pEventRecord->what)
  298.     {
  299.         case mouseDown :
  300.             err = HandleMouseDownEvent (pEventRecord);
  301.             break;
  302.  
  303.         case keyDown :
  304.         case autoKey :
  305.             err = HandleKeyEvent (pEventRecord);
  306.             break;
  307.  
  308.         case updateEvt :
  309.             err = UpdateWindow ((WindowRef) (pEventRecord->message));
  310.             break;
  311.  
  312.         case diskEvt :
  313.             if ((pEventRecord->message >> 16) != noErr)
  314.             {
  315.                 SetPt (&point, kDILeft, kDITop);
  316.                 err = DIBadMount (point, pEventRecord->message);
  317.             }
  318.             break;
  319.  
  320.         case osEvt :
  321.             err = HandleOSEvent (pEventRecord);
  322.             break;
  323.  
  324.         case kHighLevelEvent :
  325.             AEProcessAppleEvent (pEventRecord);
  326.             break;
  327.  
  328.         default :
  329.             break;
  330.     }
  331.  
  332.     return (err);
  333. }
  334.  
  335.  
  336. ////////////////////////////////////////////////////////////////////////////////
  337. //
  338. // HandleMouseDownEvent
  339. //
  340. //   This routine handles mouse down events.
  341. //
  342.  
  343. static OSErr    HandleMouseDownEvent(
  344.     EventRecord                    *pEventRecord)
  345. {
  346.     WindowRef                    windowRef;
  347.     short                        inPart;
  348.     OSErr                        err = noErr;
  349.  
  350.     // Find out what part of application mouse is in.
  351.     inPart = FindWindow (pEventRecord->where, &windowRef);
  352.  
  353.     // Dispatch off of inPart.
  354.     switch (inPart)
  355.     {
  356.         case inMenuBar :
  357.             UpdateMenus ();
  358.             err = HandleMenuCommand (MenuSelect (pEventRecord->where));
  359.             break;
  360.  
  361.         case inSysWindow :
  362.             SystemClick (pEventRecord, windowRef);
  363.             break;
  364.  
  365.         case inContent :
  366.             if (windowRef == FrontWindow ())
  367.                 err = HandleWindowCommand (windowRef);
  368.             else
  369.                 SelectWindow (windowRef);
  370.             break;
  371.  
  372.         case inDrag :
  373.             DragWindow
  374.                 (windowRef,
  375.                  pEventRecord->where,
  376.                  &(gpSBP2DemoAppData->qdGlobals.screenBits.bounds));
  377.             break;
  378.  
  379.         case inGoAway :
  380.             if (TrackGoAway (windowRef, pEventRecord->where))
  381.                 CloseSBP2DemoWindow (windowRef);
  382.             break;
  383.  
  384.         default :
  385.             break;
  386.     }
  387.  
  388.     return (err);
  389. }
  390.  
  391.  
  392. ////////////////////////////////////////////////////////////////////////////////
  393. //
  394. // HandleKeyEvent
  395. //
  396. //   This routine handles key events.
  397. //
  398.  
  399. static OSErr    HandleKeyEvent(
  400.     EventRecord                    *pEventRecord)
  401. {
  402.     char                        key;
  403.     OSErr                        err = noErr;
  404.  
  405.     // Read the key from the event record.
  406.     key = pEventRecord->message & charCodeMask;
  407.  
  408.     // We're only interested in command key down events.
  409.     if ((pEventRecord->modifiers & cmdKey) &&
  410.         (pEventRecord->what == keyDown))
  411.     {
  412.         UpdateMenus ();
  413.         err = HandleMenuCommand (MenuKey (key));
  414.     }
  415.  
  416.     return (err);
  417. }
  418.  
  419.  
  420. ////////////////////////////////////////////////////////////////////////////////
  421. //
  422. // HandleOSEvent
  423. //
  424. //   This routine handles OS events.
  425. //
  426.  
  427. static OSErr    HandleOSEvent(
  428.     EventRecord                    *pEventRecord)
  429. {
  430.     UInt32                        osEventType;
  431.     OSErr                        err = noErr;
  432.  
  433.     // Get the OS event type.
  434.     osEventType = pEventRecord->message >> 24;
  435.  
  436.     // Dispatch.
  437.     switch (osEventType)
  438.     {
  439.         case suspendResumeMessage :
  440.             if (pEventRecord->message & resumeFlag)
  441.                 gpSBP2DemoAppData->inForeground = true;
  442.             else
  443.                 gpSBP2DemoAppData->inForeground = false;
  444.             break;
  445.  
  446.         default :
  447.             break;
  448.     }
  449.  
  450.     return (err);
  451. }
  452.  
  453.  
  454. ////////////////////////////////////////////////////////////////////////////////
  455. //
  456. // HandleMenuCommand
  457. //
  458. //   This routine handles menu commands.
  459. //
  460.  
  461. static OSErr    HandleMenuCommand(
  462.     long                        menuCommand)
  463. {
  464.     short                        menuID,
  465.                                 menuItem;
  466.     OSErr                        err = noErr;
  467.  
  468.     // Get menu ID and item number from the menu command.
  469.     menuID = menuCommand >> 16;
  470.     menuItem = menuCommand & 0xFFFF;
  471.  
  472.     // Dispatch off of menu ID.
  473.     switch (menuID)
  474.     {
  475.         case kAppleMenuID :
  476.             err = HandleAppleMenuCommand (menuItem);
  477.             break;
  478.  
  479.         case kFileMenuID :
  480.             err = HandleFileMenuCommand (menuItem);
  481.             break;
  482.  
  483.         case kEditMenuID :
  484.             // Don't know if we'll ever get here.
  485.             SystemEdit (menuItem - 1);
  486.             break;
  487.  
  488.         case kCommandMenuID :
  489.             err = HandleCommandMenuCommand (menuItem);
  490.             break;
  491.  
  492.         default :
  493.             break;
  494.     }
  495.  
  496.     // Unhilite menu.
  497.     HiliteMenu (0);
  498.  
  499.     return (err);
  500. }
  501.  
  502.  
  503. ////////////////////////////////////////////////////////////////////////////////
  504. //
  505. // HandleAppleMenuCommand
  506. //
  507. //   This routine handles apple menu commands.
  508. //
  509.  
  510. static OSErr    HandleAppleMenuCommand(
  511.     short                        menuItem)
  512. {
  513.     Str255                        daName;
  514.     OSErr                        err = noErr;
  515.  
  516.     // Apple menu dispatch.
  517.     switch (menuItem)
  518.     {
  519.         case kAboutAppleMenuItem :
  520.             Alert (kAboutAlertResourceID, nil);
  521.             break;
  522.  
  523.         default :
  524.             // All non-about items are DAs.
  525.             GetMenuItemText (GetMenuHandle (kAppleMenuID), menuItem, daName);
  526.             OpenDeskAcc (daName);
  527.             break;
  528.     }
  529.  
  530.     return (err);
  531. }
  532.  
  533.  
  534. ////////////////////////////////////////////////////////////////////////////////
  535. //
  536. // HandleFileMenuCommand
  537. //
  538. //   This routine handles file menu commands.
  539. //
  540.  
  541. static OSErr    HandleFileMenuCommand(
  542.     short                        menuItem)
  543. {
  544.     OSErr                        err = noErr;
  545.  
  546.     // File menu dispatch.
  547.     switch (menuItem)
  548.     {
  549.         case kCloseFileMenuItem :
  550.             HandleCloseFileMenuCommand ();
  551.             break;
  552.  
  553.         case kQuitFileMenuItem :
  554.             QuitApplication ();
  555.             break;
  556.  
  557.         default :
  558.             break;
  559.     }
  560.  
  561.     return (err);
  562. }
  563.  
  564.  
  565. ////////////////////////////////////////////////////////////////////////////////
  566. //
  567. // HandleCommandMenuCommand
  568. //
  569. //   This routine handles extra menu commands.
  570. //
  571.  
  572. static OSErr    HandleCommandMenuCommand(
  573.     short                        menuItem)
  574. {
  575.     OSErr                        err = noErr;
  576.  
  577.     // File menu dispatch.
  578.     switch (menuItem)
  579.     {
  580.         case kLoginMenuItem:
  581.             HandleLoginMenuCommand ();
  582.             break;
  583.             
  584.         case kLogoutMenuItem:
  585.             HandleLogoutMenuCommand ();
  586.             break;
  587.         
  588.         case kQueryLoginsMenuItem:
  589. //            HandleQueryLoginsMenuCommand ();
  590.             break;
  591.         
  592.         case kStatusInquiryMenuItem:
  593.             HandleStatusInquiryMenuCommand ();
  594.             break;
  595.             
  596.         case kModeSenseMenuItem:
  597.             HandleModeSenseMenuCommand ();
  598.             break;
  599.             
  600.         case kReadBlockMenuItem:
  601.             HandleReadBlockMenuCommand ();
  602.             break;
  603.             
  604.         default :
  605.             break;
  606.     }
  607.  
  608.     return (err);
  609. }
  610.  
  611.  
  612. ////////////////////////////////////////////////////////////////////////////////
  613. //
  614. // HandleCloseFileMenuCommand
  615. //
  616. //   This routine handles the close command.
  617. //
  618.  
  619. static OSErr    HandleCloseFileMenuCommand(void)
  620. {
  621.     WindowRef                    windowRef;
  622.     OSErr                        err = noErr;
  623.  
  624.     // Get reference to front most window and close.
  625.     windowRef = FrontWindow ();
  626.     if (windowRef != kInvalidWindowRef)
  627.         err = CloseSBP2DemoWindow (windowRef);
  628.     
  629.     return (err);
  630. }
  631.  
  632.  
  633. ////////////////////////////////////////////////////////////////////////////////
  634. //
  635. // HandleLoginMenuCommand
  636. //
  637. //   This routine handles the login command.
  638. //
  639.  
  640. static OSErr    HandleLoginMenuCommand (void)
  641. {
  642.     WindowRef                    windowRef;
  643.     SBP2DemoDataPtr                pSBP2DemoData;
  644.     SBPLoginParams                sbpLoginParams;
  645.     GrafPtr                        pWindowPort;
  646.     OSErr                        err = noErr;
  647.  
  648.     // Get reference to front most window.
  649.     windowRef = FrontWindow ();
  650.  
  651.     if (windowRef != kInvalidWindowRef)
  652.     {
  653.         // Get device data.
  654.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  655.         pSBP2DemoData->lastCommand = kLoginMenuItem;
  656.         
  657.         sbpLoginParams.sbpInterfaceParams.interfaceSelector = kSampleSBPLogin;
  658.         sbpLoginParams.responseBufferPtr = 0;
  659.         sbpLoginParams.responseBufferSize = 0;
  660.  
  661.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  662.                              (SBPInterfaceParamsPtr) &sbpLoginParams);
  663.  
  664.         pSBP2DemoData->lastError = sbpLoginParams.status;
  665.         
  666.         if (sbpLoginParams.status == noErr)
  667.             pSBP2DemoData->login = true;
  668.         
  669.         // Force window update to show command status.
  670.         pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  671.         SetPortWindowPort (windowRef);
  672.         InvalRect (&(pWindowPort->portRect));
  673.     }
  674.     
  675.     return err;
  676. }
  677.  
  678.  
  679. ////////////////////////////////////////////////////////////////////////////////
  680. //
  681. // HandleLogoutMenuCommand
  682. //
  683. //   This routine handles the logout command.
  684. //
  685.  
  686. static OSErr    HandleLogoutMenuCommand (void)
  687. {
  688.     WindowRef                    windowRef;
  689.     SBP2DemoDataPtr                pSBP2DemoData;
  690.     SBPLogoutParams                sbpLogoutParams;
  691.     GrafPtr                        pWindowPort;
  692.     OSErr                        err = noErr;
  693.  
  694.     // Get reference to front most window.
  695.     windowRef = FrontWindow ();
  696.  
  697.     if (windowRef != kInvalidWindowRef)
  698.     {
  699.         // Get device data.
  700.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  701.         pSBP2DemoData->lastCommand = kLogoutMenuItem;
  702.         
  703.         sbpLogoutParams.sbpInterfaceParams.interfaceSelector = kSampleSBPLogout;
  704.  
  705.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  706.                              (SBPInterfaceParamsPtr) &sbpLogoutParams);
  707.  
  708.         pSBP2DemoData->lastError = sbpLogoutParams.status;
  709.         
  710.         if (sbpLogoutParams.status == noErr)
  711.             pSBP2DemoData->login = false;
  712.         
  713.         // Force window update to show command status.
  714.         pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  715.         SetPortWindowPort (windowRef);
  716.         InvalRect (&(pWindowPort->portRect));
  717.     }
  718.     
  719.     return err;
  720. }
  721.  
  722.  
  723. ////////////////////////////////////////////////////////////////////////////////
  724. //
  725. // HandleStatusInquiryMenuCommand
  726. //
  727. //   This routine handles the status inquiry command.
  728. //
  729.  
  730. static OSErr    HandleStatusInquiryMenuCommand (void)
  731. {
  732.     WindowRef                    windowRef;
  733.     SBP2DemoDataPtr                pSBP2DemoData;
  734.     SBPStatusInquiryParamsPtr    pSBPStatusInquiryParams;
  735.     GrafPtr                        pWindowPort;
  736.     OSErr                        err = noErr;
  737.  
  738.     // Get reference to front most window.
  739.     windowRef = FrontWindow ();
  740.  
  741.     if (windowRef != kInvalidWindowRef)
  742.     {
  743.         // Get device data.
  744.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  745.         pSBP2DemoData->lastCommand = kStatusInquiryMenuItem;
  746.         pSBPStatusInquiryParams = &(pSBP2DemoData->sbpStatusInquiryParams);
  747.         
  748.         pSBPStatusInquiryParams->sbpInterfaceParams.interfaceSelector = kSampleSBPStatusInquiry;
  749.  
  750.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  751.                              (SBPInterfaceParamsPtr) pSBPStatusInquiryParams);
  752.  
  753.         pSBP2DemoData->lastError = pSBPStatusInquiryParams->status;
  754.                 
  755.         // Force window update to show command status.
  756.         pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  757.         SetPortWindowPort (windowRef);
  758.         InvalRect (&(pWindowPort->portRect));
  759.     }
  760.     
  761.     return err;
  762. }
  763.  
  764.  
  765. ////////////////////////////////////////////////////////////////////////////////
  766. //
  767. // HandleModeSenseMenuCommand
  768. //
  769. //   This routine handles the mode sense command.
  770. //
  771.  
  772. static OSErr    HandleModeSenseMenuCommand (void)
  773. {
  774.     WindowRef                    windowRef;
  775.     SBP2DemoDataPtr                pSBP2DemoData;
  776.     SBPModeSenseParamsPtr        pSBPModeSenseParams;
  777.     GrafPtr                        pWindowPort;
  778.     OSErr                        err = noErr;
  779.  
  780.     // Get reference to front most window.
  781.     windowRef = FrontWindow ();
  782.  
  783.     if (windowRef != kInvalidWindowRef)
  784.     {
  785.         // Get device data.
  786.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  787.         pSBP2DemoData->lastCommand = kModeSenseMenuItem;
  788.         pSBPModeSenseParams = &(pSBP2DemoData->sbpModeSenseParams);
  789.         
  790.         pSBPModeSenseParams->sbpInterfaceParams.interfaceSelector = kSampleSBPModeSense;
  791.  
  792.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  793.                              (SBPInterfaceParamsPtr) pSBPModeSenseParams);
  794.  
  795.         pSBP2DemoData->lastError = pSBPModeSenseParams->status;
  796.                 
  797.         // Force window update to show command status.
  798.         pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  799.         SetPortWindowPort (windowRef);
  800.         InvalRect (&(pWindowPort->portRect));
  801.     }
  802.     
  803.     return err;
  804. }
  805.  
  806.  
  807. ////////////////////////////////////////////////////////////////////////////////
  808. //
  809. // HandleReadBlockMenuCommand
  810. //
  811. //   This routine handles the read block command.
  812. //
  813.  
  814. static OSErr    HandleReadBlockMenuCommand (void)
  815. {
  816.     WindowRef                    windowRef;
  817.     SBP2DemoDataPtr                pSBP2DemoData;
  818.     SBPReadBlockParamsPtr        pSBPReadBlockParams;
  819.     GrafPtr                        pWindowPort;
  820.     OSErr                        err = noErr;
  821.  
  822.     // Get reference to front most window.
  823.     windowRef = FrontWindow ();
  824.  
  825.     if (windowRef != kInvalidWindowRef)
  826.     {
  827.         // Get device data.
  828.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  829.         pSBP2DemoData->lastCommand = kReadBlockMenuItem;
  830.         pSBPReadBlockParams = &(pSBP2DemoData->sbpReadBlockParams);
  831.         
  832.         pSBPReadBlockParams->sbpInterfaceParams.interfaceSelector = kSampleSBPReadBlock;
  833.  
  834.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  835.                              (SBPInterfaceParamsPtr) pSBPReadBlockParams);
  836.  
  837.         pSBP2DemoData->lastError = pSBPReadBlockParams->status;
  838.                 
  839.         // Force window update to show command status.
  840.         pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  841.         SetPortWindowPort (windowRef);
  842.         InvalRect (&(pWindowPort->portRect));
  843.     }
  844.     
  845.     return err;
  846. }
  847.  
  848.  
  849. ////////////////////////////////////////////////////////////////////////////////
  850. //
  851. // HandleWindowCommand
  852. //
  853. //   This routine handles clicks in the contents of the window.
  854. //
  855.  
  856. static OSErr    HandleWindowCommand(
  857.     WindowRef                    windowRef)
  858. {
  859.     OSErr                        err = noErr;
  860.  
  861.     return (err);
  862. }
  863.  
  864.  
  865. ////////////////////////////////////////////////////////////////////////////////
  866. //
  867. // SBP2DemoInitialize
  868. //
  869. //   This routine initializes the SBPSBP2Demo application.
  870. //
  871.  
  872. static OSErr    SBP2DemoInitialize(void)
  873. {
  874.     Handle                        hMenuBarResource;
  875.     SBPDriverID                    *sbpDriverIDList = nil;
  876.     UInt32                        numSBPDrivers,
  877.                                 driverNum;
  878.     OSErr                        err = noErr;
  879.  
  880.     // Create our global data record.
  881.     gpSBP2DemoAppData = (SBP2DemoAppDataPtr)
  882.         NewPtrClear (sizeof (SBP2DemoAppData));
  883.     if (gpSBP2DemoAppData != nil)
  884.     {
  885.         gpSBP2DemoAppData->sbpClientID = kInvalidSBPClientID;
  886.         gpSBP2DemoAppData->inForeground = true;
  887.     }
  888.     else
  889.     {
  890.         err = memFullErr;
  891.     }
  892.  
  893.     // Initialize a bunch of managers.
  894.     if (err == noErr)
  895.     {
  896.         InitGraf ((Ptr) &(gpSBP2DemoAppData->qdGlobals.thePort));
  897.         InitFonts ();
  898.         InitWindows ();
  899.         InitMenus ();
  900.         InitDialogs (nil);
  901.         InitCursor ();
  902.     }
  903.  
  904.     // Create our menu bar using the defs in our resources.
  905.     if (err == noErr)
  906.     {
  907.         hMenuBarResource = GetNewMBar (kMenuBarResourceID);
  908.         if (hMenuBarResource != nil)
  909.         {
  910.             SetMenuBar (hMenuBarResource);
  911.             DisposeHandle (hMenuBarResource);
  912.             AppendResMenu (GetMenuHandle (kAppleMenuID), 'DRVR');
  913.             DrawMenuBar ();
  914.         }
  915.         else
  916.         {
  917.             err = memFullErr;//zzz what should it really be?
  918.         }
  919.     }
  920.  
  921.     // Create open application event handler.
  922.     if (err == noErr)
  923.     {
  924.         gpSBP2DemoAppData->openApplicationEventHandler =
  925.             NewAEEventHandlerProc (HandleOpenApplicationEvent);
  926.         if (gpSBP2DemoAppData->openApplicationEventHandler == nil)
  927.             err = memFullErr;
  928.     }
  929.  
  930.     // Install handler.
  931.     if (err == noErr)
  932.     {
  933.         err = AEInstallEventHandler
  934.                 (kCoreEventClass,
  935.                  kAEOpenApplication,
  936.                  gpSBP2DemoAppData->openApplicationEventHandler,
  937.                  (long) gpSBP2DemoAppData,
  938.                  false);
  939.         if (err == noErr)
  940.         {
  941.             gpSBP2DemoAppData->openApplicationEventHandlerInstalled =
  942.                 true;
  943.         }
  944.     }
  945.  
  946.     // Create open documents event handler.
  947.     if (err == noErr)
  948.     {
  949.         gpSBP2DemoAppData->openDocumentsEventHandler =
  950.             NewAEEventHandlerProc (HandleOpenDocumentsEvent);
  951.         if (gpSBP2DemoAppData->openDocumentsEventHandler == nil)
  952.             err = memFullErr;
  953.     }
  954.  
  955.     // Install handler.
  956.     if (err == noErr)
  957.     {
  958.         err = AEInstallEventHandler
  959.                 (kCoreEventClass,
  960.                  kAEOpenDocuments,
  961.                  gpSBP2DemoAppData->openDocumentsEventHandler,
  962.                  (long) gpSBP2DemoAppData,
  963.                  false);
  964.         if (err == noErr)
  965.         {
  966.             gpSBP2DemoAppData->openDocumentsEventHandlerInstalled =
  967.                 true;
  968.         }
  969.     }
  970.  
  971.     // Create print documents event handler.
  972.     if (err == noErr)
  973.     {
  974.         gpSBP2DemoAppData->printDocumentsEventHandler =
  975.             NewAEEventHandlerProc (HandlePrintDocumentsEvent);
  976.         if (gpSBP2DemoAppData->printDocumentsEventHandler == nil)
  977.             err = memFullErr;
  978.     }
  979.  
  980.     // Install handler.
  981.     if (err == noErr)
  982.     {
  983.         err = AEInstallEventHandler
  984.                 (kCoreEventClass,
  985.                  kAEPrintDocuments,
  986.                  gpSBP2DemoAppData->printDocumentsEventHandler,
  987.                  (long) gpSBP2DemoAppData,
  988.                  false);
  989.         if (err == noErr)
  990.         {
  991.             gpSBP2DemoAppData->printDocumentsEventHandlerInstalled =
  992.                 true;
  993.         }
  994.     }
  995.  
  996.     // Create quit application event handler.
  997.     if (err == noErr)
  998.     {
  999.         gpSBP2DemoAppData->quitApplicationEventHandler =
  1000.             NewAEEventHandlerProc (HandleQuitApplicationEvent);
  1001.         if (gpSBP2DemoAppData->quitApplicationEventHandler == nil)
  1002.             err = memFullErr;
  1003.     }
  1004.  
  1005.     // Install handler.
  1006.     if (err == noErr)
  1007.     {
  1008.         err = AEInstallEventHandler
  1009.                 (kCoreEventClass,
  1010.                  kAEQuitApplication,
  1011.                  gpSBP2DemoAppData->quitApplicationEventHandler,
  1012.                  (long) gpSBP2DemoAppData,
  1013.                  false);
  1014.         if (err == noErr)
  1015.         {
  1016.             gpSBP2DemoAppData->quitApplicationEventHandlerInstalled =
  1017.                 true;
  1018.         }
  1019.     }
  1020.  
  1021.     // Create device added event handler.
  1022.     if (err == noErr)
  1023.     {
  1024.         gpSBP2DemoAppData->deviceAddedEventHandler =
  1025.             NewAEEventHandlerProc (HandleDeviceAddedEvent);
  1026.         if (gpSBP2DemoAppData->deviceAddedEventHandler == nil)
  1027.             err = memFullErr;
  1028.     }
  1029.  
  1030.     // Install handler.
  1031.     if (err == noErr)
  1032.     {
  1033.         err = AEInstallEventHandler
  1034.                 (kAESampleSBP2EventClass,
  1035.                  kAESampleSBP2DeviceAdded,
  1036.                  gpSBP2DemoAppData->deviceAddedEventHandler,
  1037.                  (long) gpSBP2DemoAppData,
  1038.                  false);
  1039.         if (err == noErr)
  1040.         {
  1041.             gpSBP2DemoAppData->deviceAddedEventHandlerInstalled =
  1042.                 true;
  1043.         }
  1044.     }
  1045.  
  1046.     // Create device removed event handler.
  1047.     if (err == noErr)
  1048.     {
  1049.         gpSBP2DemoAppData->deviceRemovedEventHandler =
  1050.             NewAEEventHandlerProc (HandleDeviceRemovedEvent);
  1051.         if (gpSBP2DemoAppData->deviceRemovedEventHandler == nil)
  1052.             err = memFullErr;
  1053.     }
  1054.  
  1055.     // Install handler.
  1056.     if (err == noErr)
  1057.     {
  1058.         err = AEInstallEventHandler
  1059.                 (kAESampleSBP2EventClass,
  1060.                  kAESampleSBP2DeviceRemoved,
  1061.                  gpSBP2DemoAppData->deviceRemovedEventHandler,
  1062.                  (long) gpSBP2DemoAppData,
  1063.                  false);
  1064.         if (err == noErr)
  1065.         {
  1066.             gpSBP2DemoAppData->deviceRemovedEventHandlerInstalled =
  1067.                 true;
  1068.         }
  1069.     }
  1070.  
  1071.     // Register with the family.
  1072.     if (err == noErr)
  1073.     {
  1074.         err = RegisterSBPClientApplication
  1075.                 (&(gpSBP2DemoAppData->sbpClientID),
  1076.                  (UInt32) gpSBP2DemoAppData);
  1077.     }
  1078.  
  1079.     // Get list of drivers.
  1080.     //zzz theoretically, new ones can be added while we're doing this.
  1081.     if (err == noErr)
  1082.         err = GetSBPDriverList (nil, 0, &numSBPDrivers);
  1083.  
  1084.     if ((err == noErr) && (numSBPDrivers > 0))
  1085.     {
  1086.         sbpDriverIDList = (SBPDriverID *)
  1087.             NewPtr (numSBPDrivers * sizeof (SBPDriverID));
  1088.         if (sbpDriverIDList != nil)
  1089.         {
  1090.             err = GetSBPDriverList
  1091.                     (sbpDriverIDList, numSBPDrivers, &numSBPDrivers);
  1092.         }
  1093.         else
  1094.         {
  1095.             err = memFullErr;
  1096.         }
  1097.     }
  1098.  
  1099.     // Create a device window for each driver.
  1100.     for (driverNum = 0;
  1101.          ((driverNum < numSBPDrivers) && (err == noErr));
  1102.          driverNum++)
  1103.     {
  1104.         err = CreateSBP2Demo (sbpDriverIDList[driverNum]);
  1105.     }
  1106.  
  1107.     // Clean up.
  1108.     if (sbpDriverIDList != nil)
  1109.         DisposePtr ((Ptr) sbpDriverIDList);
  1110.  
  1111.     return (err);
  1112. }
  1113.  
  1114.  
  1115. ////////////////////////////////////////////////////////////////////////////////
  1116. //
  1117. // QuitApplication
  1118. //
  1119. //   This routine quits the application.
  1120. //
  1121.  
  1122. static OSErr    QuitApplication(void)
  1123. {
  1124.     SBP2DemoDataPtr            pSBP2DemoData,
  1125.                                 pNextSBP2DemoData;
  1126.     SBPClientID                    sbpClientID;
  1127.     OSErr                        err = noErr;
  1128.  
  1129.     if (gpSBP2DemoAppData != nil)
  1130.     {
  1131.         // Remove all of the device windows.
  1132.         pSBP2DemoData = gpSBP2DemoAppData->sbp2DemoDataList;
  1133.         while (pSBP2DemoData != nil)
  1134.         {
  1135.             pNextSBP2DemoData = pSBP2DemoData->pNextSBP2DemoData;
  1136.     
  1137.             RemoveSBP2Demo (pSBP2DemoData->sbpDriverID);
  1138.     
  1139.             pSBP2DemoData = pNextSBP2DemoData;
  1140.         }
  1141.     
  1142.         // Unregister with the family.
  1143.         sbpClientID = gpSBP2DemoAppData->sbpClientID;
  1144.         if (sbpClientID != kInvalidSBPClientID)
  1145.             UnregisterSBPClientApplication (sbpClientID);
  1146.     
  1147.         // Uninstall Apple event handlers.
  1148.         // Uninstall device removed event handler.
  1149.         if (gpSBP2DemoAppData->deviceRemovedEventHandlerInstalled)
  1150.         {
  1151.             AERemoveEventHandler
  1152.                 (kAESampleSBP2EventClass,
  1153.                  kAESampleSBP2DeviceRemoved,
  1154.                  gpSBP2DemoAppData->deviceRemovedEventHandler,
  1155.                  false);
  1156.         }
  1157.  
  1158.         if (gpSBP2DemoAppData->deviceRemovedEventHandler != nil)
  1159.         {
  1160.             DisposeRoutineDescriptor
  1161.                 (gpSBP2DemoAppData->deviceRemovedEventHandler);
  1162.         }
  1163.  
  1164.         // Uninstall device added event handler.
  1165.         if (gpSBP2DemoAppData->deviceAddedEventHandlerInstalled)
  1166.         {
  1167.             AERemoveEventHandler
  1168.                 (kAESampleSBP2EventClass,
  1169.                  kAESampleSBP2DeviceAdded,
  1170.                  gpSBP2DemoAppData->deviceAddedEventHandler,
  1171.                  false);
  1172.         }
  1173.  
  1174.         if (gpSBP2DemoAppData->deviceAddedEventHandler != nil)
  1175.         {
  1176.             DisposeRoutineDescriptor
  1177.                 (gpSBP2DemoAppData->deviceAddedEventHandler);
  1178.         }
  1179.  
  1180.         // Uninstall quit application event handler.
  1181.         if (gpSBP2DemoAppData->quitApplicationEventHandlerInstalled)
  1182.         {
  1183.             AERemoveEventHandler
  1184.                 (kCoreEventClass,
  1185.                  kAEQuitApplication,
  1186.                  gpSBP2DemoAppData->quitApplicationEventHandler,
  1187.                  false);
  1188.         }
  1189.  
  1190.         if (gpSBP2DemoAppData->quitApplicationEventHandler != nil)
  1191.         {
  1192.             DisposeRoutineDescriptor
  1193.                 (gpSBP2DemoAppData->quitApplicationEventHandler);
  1194.         }
  1195.  
  1196.         // Uninstall print documents event handler.
  1197.         if (gpSBP2DemoAppData->printDocumentsEventHandlerInstalled)
  1198.         {
  1199.             AERemoveEventHandler
  1200.                 (kCoreEventClass,
  1201.                  kAEPrintDocuments,
  1202.                  gpSBP2DemoAppData->printDocumentsEventHandler,
  1203.                  false);
  1204.         }
  1205.  
  1206.         if (gpSBP2DemoAppData->printDocumentsEventHandler != nil)
  1207.         {
  1208.             DisposeRoutineDescriptor
  1209.                 (gpSBP2DemoAppData->printDocumentsEventHandler);
  1210.         }
  1211.  
  1212.         // Uninstall open documents event handler.
  1213.         if (gpSBP2DemoAppData->openDocumentsEventHandlerInstalled)
  1214.         {
  1215.             AERemoveEventHandler
  1216.                 (kCoreEventClass,
  1217.                  kAEOpenDocuments,
  1218.                  gpSBP2DemoAppData->openDocumentsEventHandler,
  1219.                  false);
  1220.         }
  1221.  
  1222.         if (gpSBP2DemoAppData->openDocumentsEventHandler != nil)
  1223.         {
  1224.             DisposeRoutineDescriptor
  1225.                 (gpSBP2DemoAppData->openDocumentsEventHandler);
  1226.         }
  1227.  
  1228.         // Uninstall open application event handler.
  1229.         if (gpSBP2DemoAppData->openApplicationEventHandlerInstalled)
  1230.         {
  1231.             AERemoveEventHandler
  1232.                 (kCoreEventClass,
  1233.                  kAEOpenApplication,
  1234.                  gpSBP2DemoAppData->openApplicationEventHandler,
  1235.                  false);
  1236.         }
  1237.  
  1238.         if (gpSBP2DemoAppData->openApplicationEventHandler != nil)
  1239.         {
  1240.             DisposeRoutineDescriptor
  1241.                 (gpSBP2DemoAppData->openApplicationEventHandler);
  1242.         }
  1243.  
  1244.         // Dispose of global data record.
  1245.         DisposePtr ((Ptr) gpSBP2DemoAppData);
  1246.         gpSBP2DemoAppData = nil;
  1247.  
  1248.         // Set event loop to quit.
  1249.         quitSBP2DemoApp = true;
  1250.     }
  1251.  
  1252.     return (err);
  1253. }
  1254.  
  1255.  
  1256. ////////////////////////////////////////////////////////////////////////////////
  1257. //
  1258. // CreateSBP2Demo
  1259. //
  1260. //   This routine creates a new device window for the given driver.
  1261. //
  1262.  
  1263. static OSErr    CreateSBP2Demo(
  1264.     SBPDriverID                    sbpDriverID)
  1265. {
  1266.     WindowRef                    sbp2DemoWindowRef = kInvalidWindowRef;
  1267.     SBP2DemoDataPtr                pSBP2DemoData = nil;
  1268.     OSErr                        err = noErr;
  1269.  
  1270.     // Get a new window.
  1271.     sbp2DemoWindowRef =
  1272.         GetNewWindow (kSBP2DemoWindowResourceID, nil, (WindowRef) -1);
  1273.     if (sbp2DemoWindowRef == kInvalidWindowRef)
  1274.         err = -1;//zzz not really correct.
  1275.  
  1276.     // Allocate device data record.
  1277.     if (err == noErr)
  1278.     {
  1279.         pSBP2DemoData =
  1280.             (SBP2DemoDataPtr) NewPtrClear (sizeof (SBP2DemoData));
  1281.         if (pSBP2DemoData != nil)
  1282.         {
  1283.             pSBP2DemoData->sbp2DemoWindowRef = sbp2DemoWindowRef;
  1284.             pSBP2DemoData->sbpDriverID = sbpDriverID;
  1285.         }
  1286.         else
  1287.         {
  1288.             err = memFullErr;
  1289.         }
  1290.     }
  1291.  
  1292.     // Open connection to driver.
  1293.     if (err == noErr)
  1294.         err = OpenSBPDriver (sbpDriverID);
  1295.  
  1296.     // Store device data in window ref con.
  1297.     if (err == noErr)
  1298.         SetWRefCon (sbp2DemoWindowRef, (long) pSBP2DemoData);
  1299.  
  1300.     // Add device to list or clean up on error.
  1301.     if (err == noErr)
  1302.     {
  1303.         pSBP2DemoData->pNextSBP2DemoData =
  1304.             gpSBP2DemoAppData->sbp2DemoDataList;
  1305.         gpSBP2DemoAppData->sbp2DemoDataList =
  1306.             pSBP2DemoData;
  1307.     }
  1308.     else
  1309.     {
  1310.         if (pSBP2DemoData != nil)
  1311.             DisposePtr ((Ptr) pSBP2DemoData);
  1312.  
  1313.         if (sbp2DemoWindowRef != kInvalidWindowRef)
  1314.             CloseWindow (sbp2DemoWindowRef);
  1315.     }
  1316.  
  1317.     return (err);
  1318. }
  1319.  
  1320.  
  1321. ////////////////////////////////////////////////////////////////////////////////
  1322. //
  1323. // RemoveSBP2Demo
  1324. //
  1325. //   This routine removes the device window for the given driver.
  1326. //
  1327.  
  1328. static OSErr    RemoveSBP2Demo(
  1329.     SBPDriverID                    sbpDriverID)
  1330. {
  1331.     SBP2DemoDataPtr            pSBP2DemoData;
  1332.     Boolean                        found;
  1333.     OSErr                        err = noErr;
  1334.  
  1335.     // Find device for given driver.
  1336.     pSBP2DemoData = FindSBP2DemoFromSBPDriver (sbpDriverID);
  1337.     if (pSBP2DemoData != nil)
  1338.         found = true;
  1339.     else
  1340.         found = false;
  1341.  
  1342.     // Close connection to driver.
  1343.     if (found)
  1344.         CloseSBPDriver (sbpDriverID);
  1345.  
  1346.     // Close the device window.
  1347.     if (found)
  1348.         CloseWindow (pSBP2DemoData->sbp2DemoWindowRef);
  1349.  
  1350.     // Remove the device data from our list.
  1351.     if (found)
  1352.         RemoveSBP2DemoFromList (pSBP2DemoData);
  1353.  
  1354.     return (err);
  1355. }
  1356.  
  1357.  
  1358. ////////////////////////////////////////////////////////////////////////////////
  1359. //
  1360. // CloseSBP2DemoWindow
  1361. //
  1362. //   This routine closes the given device window.
  1363. //
  1364.  
  1365. static OSErr    CloseSBP2DemoWindow(
  1366.     WindowRef                    windowRef)
  1367. {
  1368.     SBP2DemoDataPtr            pSBP2DemoData;
  1369.     OSErr                        err = noErr;
  1370.  
  1371.     // Get device data.
  1372.     pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  1373.  
  1374.     // Remove the device.
  1375.     err = RemoveSBP2Demo (pSBP2DemoData->sbpDriverID);
  1376.     
  1377.     return (err);
  1378. }
  1379.  
  1380.  
  1381. ////////////////////////////////////////////////////////////////////////////////
  1382. //
  1383. // DrawSBP2Demo
  1384. //
  1385. //   This routine draws the given device window.
  1386. //
  1387.  
  1388. static OSErr    DrawSBP2Demo(
  1389.     WindowRef                    windowRef)
  1390. {
  1391.     SBP2DemoDataPtr                pSBP2DemoData;
  1392.     GrafPtr                        pWindowPort;
  1393.     Str255                        msg;
  1394.     int                            i;
  1395.     UInt8                        *p;
  1396.     OSErr                        err = noErr;
  1397.  
  1398.     // Get device data.
  1399.     pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  1400.  
  1401.     // Get window's graf port.
  1402.     pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  1403.  
  1404.     // Set port to the window's port.
  1405.     SetPortWindowPort (windowRef);
  1406.  
  1407.     // Clear window.
  1408.     EraseRect (&(pWindowPort->portRect));
  1409.     ForeColor (blackColor);
  1410.     TextSize (9);
  1411.     TextFont (4);        //monaco - why doesn't the enum work? 
  1412.  
  1413.     MoveTo (10, 20);
  1414.     DrawString ("\pLast Command: ");
  1415.     
  1416.     switch (pSBP2DemoData->lastCommand)
  1417.     {
  1418.         case kLoginMenuItem:            DrawString ("\pLogin   ");    break;
  1419.         case kLogoutMenuItem:            DrawString ("\pLogout  ");    break;
  1420.         case kQueryLoginsMenuItem:        DrawString ("\pQuery   ");    break;
  1421.         case kStatusInquiryMenuItem:    DrawString ("\pInquiry ");    break;
  1422.         case kModeSenseMenuItem:        DrawString ("\pSense   ");    break;
  1423.         case kReadBlockMenuItem:        DrawString ("\pRead    ");    break;
  1424.         default:                        DrawString ("\p(none)  ");    break;
  1425.     }
  1426.  
  1427.     sprintf ((char *) msg, "x Status = %ld", pSBP2DemoData->lastError);
  1428.     msg [0] = strlen ((char *) msg) - 1;
  1429.     DrawString (msg);
  1430.     
  1431.     if (!pSBP2DemoData->lastError) DrawString ("\p (noErr)");
  1432.     
  1433.     MoveTo (10, 40);
  1434.  
  1435.     if (pSBP2DemoData->reconnecting)
  1436.     {
  1437.         DrawString ("\pRECONNECTING");
  1438.     }
  1439.     else
  1440.     if (pSBP2DemoData->reconnectFailed)
  1441.     {
  1442.         DrawString ("\pRECONNECT FAILED");
  1443.     }
  1444.     else
  1445.     {
  1446.         if (pSBP2DemoData->login)
  1447.             DrawString ("\pLogged in");
  1448.             else DrawString ("\pNot Logged in");
  1449.     }
  1450.  
  1451.     MoveTo (10, 60);
  1452.     DrawString ("\pLast Normal Command ORB Status Notification: ");
  1453.  
  1454.     switch (pSBP2DemoData->notificationEvent)
  1455.     {
  1456.         case kSBP2NormalCommandStatus:    DrawString ("\pStatus      ");    break;
  1457.         case kSBP2NormalCommandTimeout:    DrawString ("\pTimeout     ");    break;
  1458.         case kSBP2UnsolicitedStatus:    DrawString ("\pUnsolicited ");    break;
  1459.         default:                        DrawString ("\p(none)      ");    break;
  1460.     }
  1461.  
  1462.     p = (UInt8 *) pSBP2DemoData->notificationMessage;
  1463.     if (pSBP2DemoData->notificationEvent && p)
  1464.     {
  1465.         MoveTo (20, 72);
  1466.         for (i = 0; i < pSBP2DemoData->notificationLength; i++)
  1467.         {
  1468.             sprintf ((char *) msg, "x%02lx ", (long) p[i]);
  1469.             msg [0] = strlen ((char *) msg) - 1;
  1470.             if (i < 16) DrawString (msg);
  1471.         }
  1472.         if (pSBP2DemoData->notificationLength > 16) DrawString ("\p...");
  1473.     }
  1474.  
  1475.     MoveTo (10, 92);
  1476.  
  1477.     return (err);
  1478. }
  1479.  
  1480.  
  1481. ////////////////////////////////////////////////////////////////////////////////
  1482. //
  1483. // UpdateWindow
  1484. //
  1485. //   This routine updates the given window.
  1486. //
  1487.  
  1488. static OSErr    UpdateWindow(
  1489.     WindowRef                    windowRef)
  1490. {
  1491.     Boolean                        updateNeeded,
  1492.                                 preparedUpdate;
  1493.     OSErr                        err = noErr;
  1494.  
  1495.     // Prepare window for updating.
  1496.     err = PrepareWindowForUpdating (windowRef, &updateNeeded);
  1497.     if (err == noErr)
  1498.         preparedUpdate = true;
  1499.     else
  1500.         preparedUpdate = false;
  1501.  
  1502.     // Draw the window.
  1503.     if ((err == noErr) && (updateNeeded))
  1504.         err = DrawSBP2Demo (windowRef);
  1505.  
  1506.     // Release the window from updating.
  1507.     if (preparedUpdate)
  1508.         ReleaseWindowFromUpdating (windowRef);
  1509.  
  1510.     return (err);
  1511. }
  1512.  
  1513.  
  1514. ////////////////////////////////////////////////////////////////////////////////
  1515. //
  1516. // UpdateMenus
  1517. //
  1518. //   This routine sets up the menus for the front most window.
  1519. //
  1520.  
  1521. static OSErr    UpdateMenus(void)
  1522. {
  1523.     WindowRef                    windowRef;
  1524.     SBP2DemoDataPtr                pSBP2DemoData;
  1525.     MenuHandle                    hMenu;
  1526.     OSErr                        err = noErr;
  1527.  
  1528.     // Get reference to front most window.
  1529.     windowRef = FrontWindow ();
  1530.  
  1531.     // Get handle to file menu.
  1532.     hMenu = GetMenuHandle (kFileMenuID);
  1533.  
  1534.     // Close menu item should be enabled if there is a window open.
  1535.     if (windowRef != kInvalidWindowRef)
  1536.         EnableItem (hMenu, kCloseFileMenuItem);
  1537.     else
  1538.         DisableItem (hMenu, kCloseFileMenuItem);
  1539.  
  1540.     // Get handle to Command menu.
  1541.     hMenu = GetMenuHandle (kCommandMenuID);
  1542.  
  1543.     if (windowRef == kInvalidWindowRef)
  1544.     {
  1545.         DisableItem (hMenu, kLoginMenuItem);
  1546.         DisableItem (hMenu, kLogoutMenuItem);
  1547.         DisableItem (hMenu, kQueryLoginsMenuItem);
  1548.         DisableItem (hMenu, kStatusInquiryMenuItem);
  1549.         DisableItem (hMenu, kModeSenseMenuItem);
  1550.         DisableItem (hMenu, kReadBlockMenuItem);
  1551.     }
  1552.     else
  1553.     {
  1554.         pSBP2DemoData = (SBP2DemoDataPtr) GetWRefCon (windowRef);
  1555.         if (pSBP2DemoData->login)
  1556.         {
  1557.             DisableItem (hMenu, kLoginMenuItem);
  1558.             EnableItem (hMenu, kLogoutMenuItem);
  1559.             EnableItem (hMenu, kStatusInquiryMenuItem);
  1560.             EnableItem (hMenu, kModeSenseMenuItem);
  1561.             EnableItem (hMenu, kReadBlockMenuItem);
  1562.         }
  1563.         else
  1564.         {
  1565.             EnableItem (hMenu, kLoginMenuItem);
  1566.             DisableItem (hMenu, kLogoutMenuItem);
  1567.             DisableItem (hMenu, kStatusInquiryMenuItem);
  1568.             DisableItem (hMenu, kModeSenseMenuItem);
  1569.             DisableItem (hMenu, kReadBlockMenuItem);
  1570.         }
  1571. //        EnableItem (hMenu, kQueryLoginsMenuItem);
  1572.     }
  1573.     
  1574.     return (err);
  1575. }
  1576.  
  1577.  
  1578. ////////////////////////////////////////////////////////////////////////////////
  1579. //
  1580. // UpdateCursor
  1581. //
  1582. //   This routine sets the cursor to the correct image for the given mouse
  1583. // position.
  1584. //
  1585.  
  1586. static OSErr    UpdateCursor(
  1587.     Point                        mousePosition,
  1588.     RgnHandle                    hCursorRgn)
  1589. {
  1590.     WindowRef                    windowRef;
  1591.     GrafPtr                        pWindowPort;
  1592.     Rect                        windowPortRect;
  1593.     RgnHandle                    hArrowCursorRgn = nil,
  1594.                                 hPlusCursorRgn = nil;
  1595.     OSErr                        err = noErr;
  1596.  
  1597.     // Update if we're not in background.
  1598.     if (gpSBP2DemoAppData->inForeground)
  1599.     {
  1600.         // Get reference to front most window.
  1601.         windowRef = FrontWindow ();
  1602.  
  1603.         // Initialize cursor regions.
  1604.         hArrowCursorRgn = NewRgn ();
  1605.         hPlusCursorRgn = NewRgn ();
  1606.  
  1607.         // Set plus region to front most window if it's a device.
  1608.         if (IsSBP2DemoWindow (windowRef))
  1609.         {
  1610.             // Get window's port and port rect.
  1611.             pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  1612.  
  1613.             // Set plus region to visible portion of device window.
  1614.             SetPortWindowPort (windowRef);
  1615.             SetOrigin (-(pWindowPort->portBits.bounds.left),
  1616.                        -(pWindowPort->portBits.bounds.top));
  1617.             windowPortRect = pWindowPort->portRect;
  1618.             RectRgn (hPlusCursorRgn, &windowPortRect);
  1619.             SectRgn (hPlusCursorRgn, pWindowPort->visRgn, hPlusCursorRgn);
  1620.             SetOrigin (0, 0);
  1621.         }
  1622.  
  1623.         // Set arrow region to everywhere except the other cursor regions.
  1624.         SetRectRgn (hArrowCursorRgn,
  1625.                     kExtremeNeg,
  1626.                     kExtremeNeg,
  1627.                     kExtremePos,
  1628.                     kExtremePos);
  1629.         DiffRgn (hArrowCursorRgn, hPlusCursorRgn, hArrowCursorRgn);
  1630.  
  1631.         // Change the cursor image and region.
  1632.         if (PtInRgn (mousePosition, hPlusCursorRgn))
  1633.         {
  1634.             SetCursor (*GetCursor (plusCursor));
  1635.             CopyRgn (hPlusCursorRgn, hCursorRgn);
  1636.         }
  1637.         else
  1638.         {
  1639.             SetCursor (&(gpSBP2DemoAppData->qdGlobals.arrow));
  1640.             CopyRgn (hArrowCursorRgn, hCursorRgn);
  1641.         }
  1642.     }
  1643.  
  1644.     // Clean up.
  1645.     if (hArrowCursorRgn != nil)
  1646.         DisposeRgn (hArrowCursorRgn);
  1647.     if (hPlusCursorRgn != nil)
  1648.         DisposeRgn (hPlusCursorRgn);
  1649.  
  1650.     return (err);
  1651. }
  1652.  
  1653.  
  1654. ////////////////////////////////////////////////////////////////////////////////
  1655. //
  1656. // IsSBP2DemoWindow
  1657. //
  1658. //   This routine returns true if the given window is a SBP2 device.
  1659. //
  1660.  
  1661. static Boolean    IsSBP2DemoWindow(
  1662.     WindowRef                    windowRef)
  1663. {
  1664.     // If the window is a user window, it's a device.
  1665.     if (GetWindowKind (windowRef) == kApplicationWindowKind)
  1666.         return (true);
  1667.     else
  1668.         return (false);
  1669. }
  1670.  
  1671.  
  1672. ////////////////////////////////////////////////////////////////////////////////
  1673. //
  1674. // GetMousePosition
  1675. //
  1676. //   This routine returns the current position of the mouse.
  1677. //
  1678.  
  1679. static void    GetMousePosition(
  1680.     Point                        *pMousePosition)
  1681. {
  1682.     EventRecord                    eventRecord;
  1683.  
  1684.     // Get mouse position from event manager.
  1685.     OSEventAvail (0, &eventRecord);
  1686.     *pMousePosition = eventRecord.where;
  1687. }
  1688.  
  1689.  
  1690. ////////////////////////////////////////////////////////////////////////////////
  1691. //
  1692. // HandleOpenApplicationEvent
  1693. //
  1694. //   This routine handles open application events.
  1695. //
  1696.  
  1697. static pascal OSErr    HandleOpenApplicationEvent(
  1698.     AppleEvent                    *theAppleEvent,
  1699.     AppleEvent                    *reply,
  1700.     long                        handlerRefcon)
  1701. {
  1702.     OSErr                        err = noErr;
  1703.  
  1704.     return (err);
  1705. }
  1706.  
  1707.  
  1708. ////////////////////////////////////////////////////////////////////////////////
  1709. //
  1710. // HandleOpenDocumentsEvent
  1711. //
  1712. //   This routine handles open documents events.
  1713. //zzz should we return an error?
  1714. //
  1715.  
  1716. static pascal OSErr    HandleOpenDocumentsEvent(
  1717.     AppleEvent                    *theAppleEvent,
  1718.     AppleEvent                    *reply,
  1719.     long                        handlerRefcon)
  1720. {
  1721.     OSErr                        err = noErr;
  1722.  
  1723.     return (err);
  1724. }
  1725.  
  1726.  
  1727. ////////////////////////////////////////////////////////////////////////////////
  1728. //
  1729. // HandlePrintDocumentsEvent
  1730. //
  1731. //   This routine handles print documents events.
  1732. //zzz should we return an error?
  1733. //
  1734.  
  1735. static pascal OSErr    HandlePrintDocumentsEvent(
  1736.     AppleEvent                    *theAppleEvent,
  1737.     AppleEvent                    *reply,
  1738.     long                        handlerRefcon)
  1739. {
  1740.     OSErr                        err = noErr;
  1741.  
  1742.     return (err);
  1743. }
  1744.  
  1745.  
  1746. ////////////////////////////////////////////////////////////////////////////////
  1747. //
  1748. // HandleQuitApplicationEvent
  1749. //
  1750. //   This routine handles quit application events.
  1751. //
  1752.  
  1753. static pascal OSErr    HandleQuitApplicationEvent(
  1754.     AppleEvent                    *theAppleEvent,
  1755.     AppleEvent                    *reply,
  1756.     long                        handlerRefcon)
  1757. {
  1758.     OSErr                        err = noErr;
  1759.  
  1760.     // Quit the application.
  1761.     QuitApplication ();
  1762.  
  1763.     return (err);
  1764. }
  1765.  
  1766.  
  1767. ////////////////////////////////////////////////////////////////////////////////
  1768. //
  1769. // HandleDeviceAddedEvent
  1770. //
  1771. //   This routine handles device added events.
  1772. //
  1773.  
  1774. static pascal OSErr    HandleDeviceAddedEvent(
  1775.     AppleEvent                    *theAppleEvent,
  1776.     AppleEvent                    *reply,
  1777.     long                        handlerRefcon)
  1778. {
  1779.     SBPDriverID                    sbpDriverID;
  1780.     DescType                    returnedType;
  1781.     Size                        returnedSize;
  1782.     Boolean                        inList;
  1783.     OSErr                        err = noErr;
  1784.  
  1785.     // Get driver ID from apple event.
  1786.     err = AEGetParamPtr (theAppleEvent,
  1787.                          kAESBPDriverIDKey,
  1788.                          kAESBPDriverIDType,
  1789.                          &returnedType,
  1790.                          &sbpDriverID,
  1791.                          sizeof (SBPDriverID),
  1792.                          &returnedSize);
  1793.  
  1794.     // Check if sbp driver is in our list.  This will happen if device was
  1795.     // connected, opened, disconnected, and reconnected without being closed.
  1796.     // If it's in our list, do not create a new device.
  1797.     if (err == noErr)
  1798.     {
  1799.         if (FindSBP2DemoFromSBPDriver (sbpDriverID))
  1800.             inList = true;
  1801.         else
  1802.             inList = false;
  1803.     }
  1804.  
  1805.     // Create device for added device.
  1806.     if ((err == noErr) && (!inList))
  1807.         err = CreateSBP2Demo (sbpDriverID);
  1808.  
  1809.     return (err);
  1810. }
  1811.  
  1812.  
  1813. ////////////////////////////////////////////////////////////////////////////////
  1814. //
  1815. // HandleDeviceRemovedEvent
  1816. //
  1817. //   This routine handles device removed events.
  1818. //
  1819.  
  1820. static pascal OSErr    HandleDeviceRemovedEvent(
  1821.     AppleEvent                    *theAppleEvent,
  1822.     AppleEvent                    *reply,
  1823.     long                        handlerRefcon)
  1824. {
  1825.     SBPDriverID                    sbpDriverID;
  1826.     DescType                    returnedType;
  1827.     Size                        returnedSize;
  1828.     OSErr                        err = noErr;
  1829.  
  1830.     // Get driver ID from apple event.
  1831.     err = AEGetParamPtr (theAppleEvent,
  1832.                          kAESBPDriverIDKey,
  1833.                          kAESBPDriverIDType,
  1834.                          &returnedType,
  1835.                          &sbpDriverID,
  1836.                          sizeof (SBPDriverID),
  1837.                          &returnedSize);
  1838.  
  1839.     // Create device for removed device.
  1840.     if (err == noErr)
  1841.         err = RemoveSBP2Demo (sbpDriverID);
  1842.  
  1843.     return (err);
  1844. }
  1845.  
  1846.  
  1847. ////////////////////////////////////////////////////////////////////////////////
  1848. //
  1849. // FindSBP2DemoFromSBPDriver
  1850. //
  1851. //   This routine searches for the device corresponding to the given
  1852. // SBP driver ID.
  1853. //
  1854.  
  1855. static SBP2DemoDataPtr    FindSBP2DemoFromSBPDriver(
  1856.     SBPDriverID                    sbpDriverID)
  1857. {
  1858.     SBP2DemoDataPtr            pSBP2DemoData,
  1859.                                 pPrevSBP2DemoData;
  1860.     Boolean                        found;
  1861.     OSErr                        err = noErr;
  1862.  
  1863.     // Find device for given driver.
  1864.     pSBP2DemoData = gpSBP2DemoAppData->sbp2DemoDataList;
  1865.     pPrevSBP2DemoData = nil;
  1866.     found = false;
  1867.     while ((pSBP2DemoData != nil) && (!found))
  1868.     {
  1869.         if (pSBP2DemoData->sbpDriverID == sbpDriverID)
  1870.         {
  1871.             found = true;
  1872.         }
  1873.         else
  1874.         {
  1875.             pPrevSBP2DemoData = pSBP2DemoData;
  1876.             pSBP2DemoData = pSBP2DemoData->pNextSBP2DemoData;
  1877.         }
  1878.     }
  1879.  
  1880.     return (pSBP2DemoData);
  1881. }
  1882.  
  1883.  
  1884. ////////////////////////////////////////////////////////////////////////////////
  1885. //
  1886. // RemoveSBP2DemoFromList
  1887. //
  1888. //   This routine removes the given device data record from our list.
  1889. //
  1890.  
  1891. static OSErr    RemoveSBP2DemoFromList(
  1892.     SBP2DemoDataPtr            pSBP2DemoData)
  1893. {
  1894.     SBP2DemoDataPtr            pSearchSBP2DemoData,
  1895.                                 pPrevSBP2DemoData;
  1896.     Boolean                        found;
  1897.     OSErr                        err = noErr;
  1898.  
  1899.     // Find previous device data record.
  1900.     pSearchSBP2DemoData = gpSBP2DemoAppData->sbp2DemoDataList;
  1901.     pPrevSBP2DemoData = nil;
  1902.     found = false;
  1903.     while ((pSearchSBP2DemoData != nil) && (!found))
  1904.     {
  1905.         if (pSearchSBP2DemoData == pSBP2DemoData)
  1906.         {
  1907.             found = true;
  1908.         }
  1909.         else
  1910.         {
  1911.             pPrevSBP2DemoData = pSearchSBP2DemoData;
  1912.             pSearchSBP2DemoData = pSearchSBP2DemoData->pNextSBP2DemoData;
  1913.         }
  1914.     }
  1915.  
  1916.     // Remove the device data from our list.
  1917.     if (found)
  1918.     {
  1919.         if (pPrevSBP2DemoData != nil)
  1920.         {
  1921.             pPrevSBP2DemoData->pNextSBP2DemoData =
  1922.                 pSBP2DemoData->pNextSBP2DemoData;
  1923.         }
  1924.         else
  1925.         {
  1926.             gpSBP2DemoAppData->sbp2DemoDataList =
  1927.                 pSBP2DemoData->pNextSBP2DemoData;
  1928.         }
  1929.  
  1930.         DisposePtr ((Ptr) pSBP2DemoData);
  1931.     }
  1932.  
  1933.     return (err);
  1934. }
  1935.  
  1936.  
  1937. ////////////////////////////////////////////////////////////////////////////////
  1938. ////////////////////////////////////////////////////////////////////////////////
  1939. //
  1940. // Window managing routines.
  1941. //
  1942. //   Code that needs to use window records goes here.
  1943. //
  1944. ////////////////////////////////////////////////////////////////////////////////
  1945. ////////////////////////////////////////////////////////////////////////////////
  1946.  
  1947. ////////////////////////////////////////////////////////////////////////////////
  1948. //
  1949. // PrepareWindowForUpdating
  1950. //
  1951. //   This routine prepares the given window for updating.
  1952. //
  1953.  
  1954. static OSErr    PrepareWindowForUpdating(
  1955.     WindowRef                    windowRef,
  1956.     Boolean                        *pUpdateNeeded)
  1957. {
  1958.     GrafPtr                        pWindowPort;
  1959.     OSErr                        err = noErr;
  1960.  
  1961.     // Get window's port.
  1962.     pWindowPort = (GrafPtr) GetWindowPort (windowRef);
  1963.  
  1964.     // Call window manager to begin update.
  1965.     BeginUpdate (windowRef);
  1966.  
  1967.     // Check if window needs updating.
  1968.     if (pUpdateNeeded != nil)
  1969.     {
  1970.         if (EmptyRgn (pWindowPort->visRgn))
  1971.             *pUpdateNeeded = false;
  1972.         else
  1973.             *pUpdateNeeded = true;
  1974.     }
  1975.  
  1976.     return (err);
  1977. }
  1978.  
  1979.  
  1980. ////////////////////////////////////////////////////////////////////////////////
  1981. //
  1982. // ReleaseWindowFromUpdating
  1983. //
  1984. //   This routine releases the given window from updating.
  1985. //
  1986.  
  1987. static OSErr    ReleaseWindowFromUpdating(
  1988.     WindowRef                    windowRef)
  1989. {
  1990.     OSErr                        err = noErr;
  1991.  
  1992.     // Call window manager to end update.
  1993.     EndUpdate (windowRef);
  1994.  
  1995.     return (err);
  1996. }
  1997.  
  1998.  
  1999. ////////////////////////////////////////////////////////////////////////////////
  2000. //
  2001. // CheckAllDevices
  2002. //
  2003. //   This routine checks all devices to see if their status has changed.
  2004. //
  2005.  
  2006. static void    CheckAllDevices (void)
  2007. {
  2008.     SBP2DemoDataPtr                pSBP2DemoData;
  2009.     SBPStatusParams                sbpStatusParams;
  2010.     Boolean                        oldReconnecting, oldReconnectFailed, oldLogin;
  2011.     UInt32                        oldNotificationCounter;
  2012.     GrafPtr                        pWindowPort;
  2013.     OSErr                        err = noErr;
  2014.  
  2015.     pSBP2DemoData = gpSBP2DemoAppData->sbp2DemoDataList;
  2016.     while (pSBP2DemoData)
  2017.     {
  2018.         oldLogin = pSBP2DemoData->login;
  2019.         oldReconnecting = pSBP2DemoData->reconnecting;
  2020.         oldReconnectFailed = pSBP2DemoData->reconnectFailed;
  2021.         oldNotificationCounter = pSBP2DemoData->notificationCounter;
  2022.         
  2023.         sbpStatusParams.sbpInterfaceParams.interfaceSelector = kSampleSBPStatus;
  2024.  
  2025.         err = CallSBPDriver (pSBP2DemoData->sbpDriverID,
  2026.                              (SBPInterfaceParamsPtr) &sbpStatusParams);
  2027.         
  2028.         if (err == noErr)
  2029.         {
  2030.             if ((sbpStatusParams.login != oldLogin) ||
  2031.                 (sbpStatusParams.reconnecting != oldReconnecting) ||
  2032.                 (sbpStatusParams.reconnectFailed != oldReconnectFailed) ||
  2033.                 (sbpStatusParams.notificationCounter != oldNotificationCounter))
  2034.             {
  2035.                 pSBP2DemoData->login = sbpStatusParams.login;
  2036.                 pSBP2DemoData->reconnecting = sbpStatusParams.reconnecting;
  2037.                 pSBP2DemoData->reconnectFailed = sbpStatusParams.reconnectFailed;
  2038.                 pSBP2DemoData->notificationCounter = sbpStatusParams.notificationCounter;
  2039.                 pSBP2DemoData->notificationEvent = sbpStatusParams.notificationEvent;
  2040.                 pSBP2DemoData->notificationLength = sbpStatusParams.notificationLength;
  2041.                 pSBP2DemoData->notificationMessage = sbpStatusParams.notificationMessage;
  2042.                 
  2043.                 // Force an update on the window
  2044.                 pWindowPort = (GrafPtr) GetWindowPort (pSBP2DemoData->sbp2DemoWindowRef);
  2045.                 SetPortWindowPort (pSBP2DemoData->sbp2DemoWindowRef);
  2046.                 InvalRect (&(pWindowPort->portRect));
  2047.             }
  2048.         }
  2049.         
  2050.         pSBP2DemoData = pSBP2DemoData->pNextSBP2DemoData;
  2051.     }
  2052. }
  2053.  
  2054.  
  2055.